package com.hedl.practice.diyJava.multithreading.reentrantLock.condition.test;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition提供的await()、signal()、signalAll()原理和synchronized锁对象的wait()、notify()、notifyAll()是一致的，并且其行为也是一样的：
 *      await()会释放当前锁，进入等待状态；
 *      signal()会唤醒某个等待线程；
 *      signalAll()会唤醒所有等待线程；
 *      唤醒线程从await()返回后需要重新获得锁。
 *
 * 此外，和tryLock()类似，await()可以在等待指定时间后，如果还没有被其他线程通过signal()或signalAll()唤醒，可以自己醒来
 *      if (condition.await(1, TimeUnit.SECOND)) {
 *          // 被其他线程唤醒
 *      } else {
 *          // 指定时间内没有被其他线程唤醒
 *      }
 *
 * 小结
 *      Condition可以替代wait和notify；
 *      Condition对象必须从Lock对象获取。
 */
public class TaskQueue {
    private final Lock lock = new ReentrantLock();      // 锁
    private final Condition condition = lock.newCondition();    //获得线程暂停和唤醒功能
    private Queue<String> queue = new LinkedList<>();

    public void addTask(String s){
        lock.lock();    //锁
        try {
            queue.add(s);
            condition.signalAll();      //唤醒全部线程
        }finally {
            lock.unlock();      //释放锁
        }
    }

    public String getTask(){
        lock.lock();        //锁
        try{
            while(queue.isEmpty()){
                condition.await();      //休眠
            }
            return queue.remove();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();      //释放锁
        }

    }
}
